package cn.zhaozhiqi.template;

import cn.zhaozhiqi.dto.GeoSearchResult;
import org.springframework.data.geo.*;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.List;
import java.util.stream.Collectors;

public class MyRedisTemplate {
    private RedisTemplate redisTemplate;

    public MyRedisTemplate(RedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    //将Geo坐标存入redis
    public void addGeo(String key, Double longitude, Double latitude, Long id) {
        //获取经纬度存入geo的第二个参数point
        Point point = new Point(longitude, latitude);
        redisTemplate.opsForGeo().add(key, point, id);
    }

    //范围搜索
    /**
     * 坐标搜索
     *
     * @param key       ： 司机坐标的key
     * @param longitude ：中心点的经度
     * @param latitude  ：中心点的维度
     * @param radius    ：搜索的半径
     * @param limit     ：匹配几个成员
     * @return ：命中的结果
     */
    public List<GeoSearchResult> searchGeo(String key, double longitude, double
            latitude, double radius, Long limit) {
        //指定中心坐标，千米为单位
        Circle circle = new Circle(new Point(longitude, latitude), new
                Distance(radius, Metrics.KILOMETERS));
        //GEO搜索的参数
        RedisGeoCommands.GeoRadiusCommandArgs args
                = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs();
        //结果中包含 距离
        args.includeDistance()
                //结果中包含坐标
                .includeCoordinates()
                //按照中心点距离近到远排序
                .sortAscending()
                //匹配前几个司机
                .limit(limit);
        GeoResults<RedisGeoCommands.GeoLocation<Object>> geoResults =
                redisTemplate.opsForGeo().radius(key, circle, args);
        //拿到GEO结果列表
        List<GeoResult<RedisGeoCommands.GeoLocation<Object>>> geoResultList =
                geoResults.getContent();
        if(geoResultList.size() == 0){
            return null;
        }
        //把结果取出来，组装为List结果
        List<GeoSearchResult> geoSearchResultList =
                geoResultList.stream().map(result -> {
                    //距离
                    double distance = result.getDistance().getValue();
                    String unit = result.getDistance().getUnit();
                    //成员：member
                    Object member = result.getContent().getName();
                    //经纬度
                    double lon = result.getContent().getPoint().getX();
                    double lat = result.getContent().getPoint().getY();
                    return new GeoSearchResult(distance, unit, member, lon, lat);
                }).collect(Collectors.toList());
        //返回找到的司机
        return geoSearchResultList;
    }
}
